#include "Drawable.h"

#include <SERender/Renderer/Renderer.h>
#include <SERender/Drive/Drive.h>

namespace SEngine
{
    void Drawable::Draw(Renderer & renderer)
    {
        if (!IsValid()) {
            return;
        }
        m_mesh->Bind();
        if (m_material) {
            renderer.GetDrive()->SetPipeLineState(m_material.Value().GetPSO());
            m_material.Value().Bind();
        }
        switch (m_renderOpt.api)
        {
        case DrawElements:
            renderer.GetDrive()->DrawElements(m_renderOpt.mode, static_cast<int>(m_mesh->GetElementSize()), ElemType::UNSIGNED_INT, (void*)0, m_renderOpt.instanceCount);
            break;
        case DrawArrays:
            renderer.GetDrive()->DrawArrays(m_renderOpt.mode, 0, static_cast<int>(m_mesh->GetElementSize()), m_renderOpt.instanceCount);
            break;        
        default:
            break;
        }
        if (m_material)
            m_material.Value().Unbind();
        m_mesh->Unbind();
    }

    Drawable &Drawable::SetMesh(std::shared_ptr<Mesh> mesh)
    {
        m_mesh = mesh;
        return *this;
    }

    Drawable &Drawable::SetMaterial(ResRef<Material> material)
    {
        m_material = material;
        return *this;
    }

} // namespace SEngine

